package com.boomsecret.concurrent;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;

/**
 * Created by wangjinliang on 2018/8/6.
 */
public class ForkJoinPoolDemo {
    public static void main(String[] args) throws Exception {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        SumTask sumTask = new SumTask(1, 1000000);
        ForkJoinTask<Long> results = forkJoinPool.submit(sumTask);
        forkJoinPool.awaitTermination(2, TimeUnit.SECONDS);
        forkJoinPool.shutdown();

        System.out.println(results.get());
        System.out.println(results.getRawResult());
    }

    static class SumTask extends RecursiveTask<Long> {
        private static final int MAX_LENGTH = 100;
        private int startIndex;
        private int endIndex;

        SumTask(int startIndex, int endIndex) {
            super();
            this.startIndex = startIndex;
            this.endIndex = endIndex;
        }

        @Override
        protected Long compute() {
            long sum = 0;
            if ((endIndex - startIndex + 1) <= MAX_LENGTH) {
                for (int index = startIndex; index <= endIndex; index ++) {
                    sum += index;
                }
            } else {
                int middle = (endIndex + startIndex) / 2;
                SumTask leftTask = new SumTask(startIndex, middle);
                SumTask rightTask = new SumTask(middle + 1, endIndex);
                leftTask.fork();
                rightTask.fork();
                sum = leftTask.join() + rightTask.join();
            }
            return sum;
        }
    }
}
